<script lang="ts" setup>
import type { Project, TableRequestData } from "@/common/apis/dashboard/type"
import { deleteDataApi, getModuleSearch } from "@/common/apis/dashboard"
import { getProjectModules, setProjectInfo } from "@/common/utils/cache/local-storage"
import { ProjectRoutes } from "@/router"
import { useRouter } from "vue-router"
import { usePagination } from "@@/composables/usePagination"
import { FormTypeEnum } from "@@/constants/other-keys"
import { isEmpty } from "xe-utils"
import Export from "./components/export.vue"
import Card from "./components/card.vue"
import CreateOrUpdate from "./components/create-or-update.vue"
import { useTagsViewStore } from "@/pinia/stores/tags-view"

defineOptions({
  // 命名当前组件
  name: "Dashboard"
})
const router = useRouter()
const cards = ref<Project[]>([])
const { paginationData } = usePagination()
const materialShow = ref<boolean>(true)
const tagsViewStore = useTagsViewStore()
const isGrid = ref<boolean>(true)
const loading = ref<boolean>(true)
const tags = ref([{ key: "0", value: "全部" }, { key: "1", value: "最近使用" }])
const tag = ref("0")
const dialogVisible = ref<boolean>(false)
const editDialogRef = ref()
const curId = ref()
const dialogType = ref<FormTypeEnum>(FormTypeEnum.CREATE)
const tableRef = ref()
const dialogExportVisible = ref<boolean>(false)
const productImg = ref([
  {
    url: "@/assets/images/dashboard/product-bg.png",
    path: "/productIntroduction.pdf"
  },
  {
    url: "@/assets/images/dashboard/productUserManual.png",
    path: "/productIntroduction.pdf"
  }
])
// 无限滚动状态
const isLoading = ref(false)
const hasMoreData = ref(true)
const cardScrollContainer = ref()

// 添加项目
function handleAddProject() {
  dialogType.value = FormTypeEnum.CREATE
  dialogVisible.value = true
}

function handleDetail(row: Project) {
  const modules: string[] = JSON.parse(row.project_modules)
  if (modules.length == 1 && modules.indexOf("evaluate") != -1) {
    ElMessage.warning("评估模块不存在")
    return
  }
  setProjectInfo(JSON.stringify(row))
  redirect()
}

function handleSearch(item: string) {
  tag.value = item
  if (paginationData.currentPage === 1) {
    getTableData()
  } else {
    paginationData.currentPage = 1
  }
}

function getTableData() {
  // 重置状态
  hasMoreData.value = true
  paginationData.currentPage = 1

  const params: TableRequestData = {
    current_page: paginationData.currentPage,
    size: paginationData.pageSize,
    ...(tag.value === "1" ? { used_time: getSevenDaysAgo() } : {})
  }
  loading.value = true
  return getModuleSearch(params).then(({ data }) => {
    // 检查是否还有更多数据
    hasMoreData.value = data.rows.length >= paginationData.pageSize
    cards.value = data.rows
    paginationData.total = data.total
  }).catch(() => {
    cards.value = []
    hasMoreData.value = false
  }).finally(() => {
    loading.value = false
    // 检查是否需要立即加载更多
    checkAndLoadMore()
  })
}

function getSevenDaysAgo() {
  const now = new Date()
  const sevenDaysAgo = new Date(now)
  sevenDaysAgo.setDate(now.getDate() - 7)
  // 格式化日期为 YYYY-MM-DD
  const year = sevenDaysAgo.getFullYear()
  const month = String(sevenDaysAgo.getMonth() + 1).padStart(2, "0")
  const day = String(sevenDaysAgo.getDate()).padStart(2, "0")
  return `${year}-${month}-${day}`
}

function redirect() {
  const modules = getProjectModules()
  for (const item of ProjectRoutes[0].children || []) {
    if (modules.includes(item.meta?.moduleName as string)) {
      tagsViewStore.delAllViews()
      router.replace({ path: item.path })
      break
    }
  }
}

function closeDialog(type?: string) {
  dialogVisible.value = false
  handleSearch(tag.value)
  if (!isEmpty(type)) {
    redirect()
  }
}

function handlePdfUrl(url: string) {
  // 使用window.open直接打开PDF
  window.open(url, "_blank")
}

function handleDelete(row: Project) {
  ElMessageBox.confirm(`正在删除项目：${row.project_name}，确认删除？`, "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning"
  }).then(() => {
    deleteDataApi([row.project_id]).then(() => {
      ElMessage.success("删除成功")
      getTableData()
    })
  })
}

// 无限滚动配置
const infiniteScrollConfig = {
  // 距离底部多少像素时触发加载
  distance: 100,
  // 是否禁用
  disabled: computed(() => isLoading.value || !hasMoreData.value),
  // 立即检查
  immediate: true
}

// 修改 loadData 函数，确保返回 Promise
function loadData() {
  // 防止重复加载
  if (isLoading.value || !hasMoreData.value) {
    return Promise.resolve()
  }
  isLoading.value = true
  paginationData.currentPage++
  const params = {
    current_page: paginationData.currentPage,
    size: paginationData.pageSize,
    ...(tag.value === "1" ? { used_time: getSevenDaysAgo() } : {})
  }
  return getModuleSearch(params)
    .then(({ data }) => {
      // 检查是否还有更多数据
      hasMoreData.value = data.rows.length >= paginationData.pageSize
      // 追加新数据
      cards.value = [...cards.value, ...data.rows]
      // 更新总数
      paginationData.total = data.total
    })
    .catch((error) => {
      console.error("加载失败:", error)
      hasMoreData.value = false
    })
    .finally(() => {
      isLoading.value = false
      checkAndLoadMore()
      return Promise.resolve()
    })
}

// 检查并加载更多数据（如果内容不足以滚动）
function checkAndLoadMore() {
  if (!isGrid.value) {
    nextTick(() => {
      const scrollContainer = tableRef.value?.$el.querySelector(".el-scrollbar__wrap")
      const contentContainer = tableRef.value?.$el.querySelector(".el-scrollbar__view")

      if (scrollContainer && contentContainer) {
        // 判断是否需要加载更多数据
        const isScrollable = (scrollContainer.scrollHeight < scrollContainer.clientHeight || contentContainer.clientHeight < scrollContainer.scrollHeight)

        if (isScrollable && hasMoreData.value) {
          // 手动加载更多数据
          loadData()
        }
      }
    })
  } else {
    nextTick(() => {
      cardScrollContainer.value = document.querySelector(".custom-card-container")
      const isScrollable = cardScrollContainer.value.scrollHeight > cardScrollContainer.value.clientHeight
      if (!isScrollable && hasMoreData.value) {
        loadData()
      }
    })
  }
}

function handleExport(row: Project) {
  dialogExportVisible.value = !dialogExportVisible.value
  curId.value = row.project_id
}

// 添加卡片滚动处理函数
function handleCardScroll() {
  if (!cardScrollContainer.value || !isGrid.value) return

  const {
    scrollTop,
    scrollHeight,
    clientHeight
  } = cardScrollContainer.value

  // 当距离底部 100px 时触发加载
  if (scrollHeight - scrollTop - clientHeight <= 100) {
    loadData()
  }
}

// 修改 onMounted 钩子，确保正确获取卡片容器
onMounted(() => {
  handleSearch(tag.value)
  // 为表格添加滚动监听
  nextTick(() => {
    const tableScrollContainer = tableRef.value?.$el.querySelector(".el-scrollbar__wrap")
    if (tableScrollContainer) {
      tableScrollContainer.addEventListener("scroll", () => {
        const scrollDistance = tableScrollContainer.scrollHeight - tableScrollContainer.scrollTop - tableScrollContainer.clientHeight
        if (scrollDistance <= 100) {
          loadData()
        }
      })
      // 检查内容高度并加载更多数据
      checkAndLoadMore()
    }

    cardScrollContainer.value = document.querySelector(".custom-card-container")
    if (cardScrollContainer.value) {
      cardScrollContainer.value.addEventListener("scroll", handleCardScroll)
    }
  })
})

onUnmounted(() => {
  if (cardScrollContainer.value) {
    cardScrollContainer.value.removeEventListener("scroll", handleCardScroll)
  }
})
</script>

<template>
  <div class="app-container dash-container pager-container">
    <div class="header-operate flex-between">
      <span class="title">456456</span>
      <div class="operate">
        <div class="btn" @click="handleAddProject">
          <div class="btn-img">
            <img src="@@/assets/images/dashboard/bh.png">
            <span>我的项目</span>
          </div>
          <el-icon><Plus /></el-icon>
        </div>
      </div>
    </div>
    <div class="content">
      <div class="material-square" :class="{ active: materialShow }">
        <div class="material-square-content">
          <div class="header flex-between">
            <div>产品介绍</div>
            <el-link :underline="false" @click="() => materialShow = false">
              <el-icon :size="18">
                <Close />
              </el-icon>
            </el-link>
          </div>
          <div class="ms-flex-content">
            <div class="msfc-item" v-for="item in productImg" @click="handlePdfUrl(item.path)" />
            <!-- <div v-for="item in productImg" :key="item.path" :style="`background-image: url(${item.url})`" @click="handlePdfUrl(item.path)" class="msfc-item"> -->
          </div>
        </div>
      </div>
      <div v-loading="loading" class="content-other">
        <div class="search-header">
          <div class="flex-between">
            <div class="flex-y-center tag">
              <span v-for="(item, index) in tags" :key="index" :class="{ active: tag === item.key }" v-throttle="() => handleSearch(item.key)">{{ item.value }}</span>
            </div>
            <div class="flex-y-center sh-operate">
              <div class="sh-btn" :class="{ active: isGrid }" @click="() => isGrid = true">
                <el-tooltip content="卡片" placement="bottom">
                  <SvgIcon name="table-grid" />
                </el-tooltip>
              </div>
              <div class="sh-btn" :class="{ active: !isGrid }" @click="() => isGrid = false">
                <el-tooltip content="列表" placement="bottom">
                  <SvgIcon name="table-list" />
                </el-tooltip>
              </div>
              <div v-show="!materialShow" class="sh-btn" @click="() => materialShow = true">
                <el-tooltip content="产品介绍" placement="bottom">
                  <SvgIcon name="table-star" />
                </el-tooltip>
              </div>
            </div>
          </div>
        </div>
        <div v-if="isGrid" class="cpi-content-main">
          <div
            class="custom-card-container"
            ref="cardScrollContainer"
            v-infinite-scroll="loadData"
            :infinite-scroll-disabled="infiniteScrollConfig.disabled"
            :infinite-scroll-distance="infiniteScrollConfig.distance"
            :infinite-scroll-immediate="infiniteScrollConfig.immediate"
          >
            <template v-for="(card, index) in cards" :key="index">
              <Card
                class="card-item"
                :card="card"
                @handle-delete="handleDelete"
                @handle-export="handleExport"
                @handle-view="handleDetail"
                @toggle-select="handleDetail"
              />
            </template>
            <div class="card-loading-indicator">
              <div v-if="isLoading" class="loading-more">
                <el-icon class="is-loading">
                  <Loading />
                </el-icon>
                <span>加载中...</span>
              </div>
              <div v-else-if="hasMoreData" class="loading-more">
                <i class="fas fa-angle-double-down el-icon" />
                <span>下拉加载更多数据...</span>
              </div>
              <div v-else-if="!hasMoreData && cards.length > 0" class="no-more-data">
                <span>没有更多数据了</span>
              </div>
              <div v-else-if="cards.length === 0" class="no-data">
                <span>暂无数据</span>
              </div>
            </div>
          </div>
        </div>
        <div v-else class="cpi-content-main">
          <el-auto-resizer>
            <template #default="{ height, width }">
              <el-table ref="tableRef" :data="cards" v-loading="loading" :height="height" :width="width" show-overflow-tooltip>
                <el-table-column prop="project_name" label="项目" header-align="left" width="300">
                  <template #default="{ row }">
                    <el-space class="project-name" :size="16">
                      <img src="@@/assets/images/dashboard/bh.png">
                      <span>{{ row.project_name }}</span>
                    </el-space>
                  </template>
                </el-table-column>
                <el-table-column prop="project_describe" label="描述" header-align="left" min-width="250" />
                <el-table-column prop="create_time" label="创建时间" header-align="left" width="250" />
                <el-table-column fixed="right" label="操作" align="center" header-align="center" width="250">
                  <template #default="scope">
                    <el-space :size="12">
                      <el-link
                        :underline="false" @click.stop v-throttle="() => handleDetail(scope.row)" title="查看"
                        class="cpi-content-operate"
                      >
                        <el-icon :size="18">
                          <View />
                        </el-icon>
                      </el-link>
                      <!-- <el-link
                        :underline="false" @click.stop v-throttle="() => handleExport(scope.row)" title="导出"
                        class="cpi-content-operate"
                      >
                        <el-icon :size="18">
                          <Download />
                        </el-icon>
                      </el-link> -->
                      <el-link
                        :underline="false" type="danger"
                        @click.stop v-throttle="() => handleDelete(scope.row)" title="删除"
                      >
                        <el-icon :size="18">
                          <Delete />
                        </el-icon>
                      </el-link>
                    </el-space>
                  </template>
                </el-table-column>
              </el-table>
            </template>
          </el-auto-resizer>
        </div>
      </div>
    </div>

    <CreateOrUpdate
      ref="editDialogRef" :id="curId" :dialog-type="dialogType" :visible="dialogVisible"
      @close-dialog="closeDialog"
    />
    <Export ref="exportDialogRef" :id="curId" :visible="dialogExportVisible" @close-dialog="closeDialog" />
  </div>
</template>

<style lang="scss" scoped>
@import "@@/assets/styles/mixins.scss";

$header-operate: 80px;
$material-square: 252px;

.custom-card-container {
  grid-auto-rows: auto;
}

.pager-container {
  padding-bottom: auto !important;
}

.dash-container {
  height: calc(100% - var(--v3-header-height));
  padding-top: $header-operate;
}

.content {
  flex-grow: 1;
  height: calc(100%);
  display: flex;
  flex-direction: column;
}

.header-operate {
  position: absolute;
  height: $header-operate - 1px;
  width: calc(100% - 40px);
  background-color: var(--el-bg-color-page);
  top: 0;
  z-index: 5;
  box-sizing: border-box; /* 确保边框和内边距不影响宽度 */
  & .title {
    font-size: 18px;
  }
  & .operate {
    flex: 1;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    & .btn {
      width: 260px;
      font-weight: 500;
      border-radius: 4px 4px 4px 4px;
      border: 1px solid rgba(64, 158, 255, 0.5);
      padding: 16px;
      display: flex;
      justify-content: space-between;
      cursor: pointer;
      .btn-img {
        display: flex;
        gap: var(--main-padding);
        font-size: 14px;
        img {
          width: 14px;
          height: 14px;
        }
      }
      &:hover {
        background-color: var(--el-border-color);
      }
    }
  }
}

.material-square {
  flex: 0 0 auto;
  height: $material-square;
  height: 0;
  background: var(--v3-header-bg-color);
  border-radius: 6px;
  transform: translateY(-100%);
  opacity: 0;
  overflow: hidden;
  transition:
    transform 0.5s ease,
    opacity 0.5s ease,
    height 0.5s ease,
    padding 0.5s ease,
    margin 0.5s ease;
  position: relative;

  .material-square-content {
    position: absolute;
    height: $material-square;
    width: calc(100%);
    height: calc(100%);
    display: flex;
    flex-direction: column;
    top: 0;
    left: 0;
    padding: 22px 22px 0 22px;

    .header {
      margin-bottom: var(--main-padding);
      font-weight: 500;
    }

    .ms-flex-content {
      flex: 1;
      display: flex;
      flex-direction: row;
      overflow-x: auto;
      gap: var(--main-padding);
      @extend %scrollbar;

      .msfc-item:first-child {
        flex: 0 0 auto;
        width: 296px;
        height: 170px;
        cursor: pointer;
        background-image: url("@@/assets/images/dashboard/product-bg.png");
      }
      .msfc-item:last-child {
        flex: 0 0 auto;
        width: 296px;
        height: 170px;
        cursor: pointer;
        background-image: url("@@/assets/images/dashboard/productUserManual.png");
      }
    }
  }

  &.active {
    height: 252px;
    transform: translateY(0);
    transition:
      transform 0.5s ease,
      opacity 0.5s ease,
      height 0.5s ease,
      padding 0.5s ease,
      margin 0.5s ease;
    margin-bottom: 22px;
    opacity: 1;
    .material-square-content {
      height: 252px;
    }
  }
}

.search-header {
  padding: 0 0 16px 0px;

  .tag {
    gap: var(--main-padding);
    span {
      cursor: pointer;
      &.active {
        color: var(--el-color-primary);
      }
    }
  }
}

:deep(.el-card__body) {
  --el-card-padding: 0px;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}

:deep(.el-table) {
  --el-table-header-bg-color: transparent;
  background-color: transparent;

  & .el-table__cell {
    padding: 15px 0;

    & .cell {
      padding: 0;
    }
  }

  & tr {
    background-color: transparent;
  }

  & .el-table__header-wrapper tr th.el-table-fixed-column--left {
    background-color: var(--el-bg-color-page);
  }
  & .el-table__header-wrapper tr th.el-table-fixed-column--right {
    background-color: var(--el-bg-color-page);
  }
}

/* 修改卡片视图的加载指示器样式 */
.card-loading-indicator {
  grid-column: 1 / -1;
  height: 20px;
  padding: 20px 0;
  text-align: center;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-top: 10px;

  .loading-more,
  .no-more-data,
  .no-data {
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #909399;
    font-size: 14px;

    .el-icon {
      margin-right: 8px;
    }
  }

  .no-more-data,
  .no-data {
    color: #c0c4cc;
  }
}
</style>
